package com.lissic.lng.activities;

import android.content.Context;
import android.os.AsyncTask;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;

public class SlidingActivity{
	
	//手指滚动显示和隐藏menu时，手指滑动需要达到的速度。
	private static final int SNAP_VELCITY = 200;
	//屏幕的宽度
	private int screenWidth;
	//menu最多可以滑到做边缘。值由menu布局的宽度来定，当marginLeft到达此致之后，不能减少
	private int leftEdge;
	//menu最多可以滑到的右边缘，值恒为0
	private int rightEdge = 0;
	//menu完全显示时，留给content的宽度值
	private int menuPading = 80;
	//住内容布局
	private View content;
	//menu布局
	private View menu;
	//menu布局的参数，通过此参数来更改leftMargin的值
	private LinearLayout.LayoutParams menuParms;
	//记录手指按下时的横坐标
	private float xDown;
	//记录手指移动的距离
	private float xMove;
	//记录手指抬起时的横坐标
	private float xUp;
	//menu当前是隐藏还是显示，只有完全显示或隐藏式才会更改此值，滑动过程中此值无效
	private boolean isMenuVisible;
	//用于计算手指滑动的速度
	private VelocityTracker mVelocityTracker;
	private Context context;
	public SlidingActivity(Context context,View content,View menu){
		this.content = content;
		this.menu = menu;
		this.context = context;
	}
	//初始化
	public void initValues() {
		//获取屏幕的宽度
		WindowManager window = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
		screenWidth = window.getDefaultDisplay().getWidth();
		//初始化控件
		menuParms = (LayoutParams) menu.getLayoutParams();
		//设置menu的宽度
		menuParms.width = screenWidth - menuPading;
		//menu左边缘的值为负值
		leftEdge = -menuParms.width;
		//设置menu的左边距
		menuParms.leftMargin = leftEdge;
		//设置content的宽度为屏幕的宽度
		content.getLayoutParams().width = screenWidth;
		
	}
	
	public boolean onTouch(View v, MotionEvent event) {
		createVelocity(event);
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN://按下
			xDown = event.getRawX();//获取按下的坐标
			break;
		case MotionEvent.ACTION_MOVE://移动
			//手指移动时，对比按下时的横坐标，计算出移动的距离，来调整menu的leftmargin的值
			xMove = event.getRawX();
			int distanceX = (int)(xMove-xDown);
			if(isMenuVisible){//如果为显示
				menuParms.leftMargin = distanceX;
			}else{
				menuParms.leftMargin = leftEdge + distanceX;
			}
			if(menuParms.leftMargin < leftEdge){
				menuParms.leftMargin = leftEdge;
			}else if(menuParms.leftMargin > rightEdge){
				menuParms.leftMargin = rightEdge;
			}
			//设置menu的参数值
			menu.setLayoutParams(menuParms);
			break;
		case MotionEvent.ACTION_UP://手指抬起
			//手指抬起时，进行判断当前手势的意图，从而决定是滚到到menu界面还是content界面
			xUp = event.getRawX();
			if(wantToShowMenu()){
				if(shouldScrollMenu()){
					scrollToMenu();//显示menu
				}else{
					scorllToContent();//显示content
				}
			}else if(wantToShowContent()){
				if(shouldScrollContent()){
					scorllToContent();//显示content
				}else {
					scrollToMenu();//显示menu
				}
			}
		recyleVelocityTracker();
			break;
		}
		return true;
	}
	
	//回收VelocityTracker对象
	private void recyleVelocityTracker() {
		mVelocityTracker.recycle();
		mVelocityTracker = null;
	}

	private boolean wantToShowContent() {
		return xUp - xDown < 0 && isMenuVisible;
	}
	
	//如果移动距离为负值，则尝试显示content界面
	private boolean wantToShowMenu() {
		return xUp - xDown > 0 && !isMenuVisible;
	}


	//显示content界面
	private void scorllToContent() {
		new ScrollTask().execute(-30);
	}

	//将界面滑动到menu 速度 为30
	private void scrollToMenu() {
		new ScrollTask().execute(30);
	}
	

	//如果移动的距离为正值，则尝试显示menu界面
	private boolean shouldScrollMenu() {
		return xUp - xDown > screenWidth/2 || getVelocity() > SNAP_VELCITY;
	}
	//
	private boolean shouldScrollContent() {
		return xUp - xDown + menuPading > screenWidth/2 || getVelocity() > SNAP_VELCITY;
	}
	
	//获取手指移动的速度
	private int getVelocity() {
		mVelocityTracker.computeCurrentVelocity(1000);
		int velocity = (int) mVelocityTracker.getXVelocity();
		return Math.abs(velocity);
	}

	
	/**
	 * 创建VelocityTracker对象，并将content的触摸事件加入到VelocityTracker当中
	 * @param event
	 */
	private void createVelocity(MotionEvent event) {
		if(mVelocityTracker == null){
			mVelocityTracker = VelocityTracker.obtain();
		}
		mVelocityTracker.addMovement(event);
	}
	class ScrollTask extends AsyncTask<Integer, Integer, Integer>{
		
		@Override
		protected Integer doInBackground(Integer... speed) {
			int leftMargin = menuParms.leftMargin;
			while(true){
				leftMargin = leftMargin + speed[0];
				if(leftMargin>rightEdge){
					leftMargin = rightEdge;
					break;
				}
				if(leftMargin<leftEdge){
					leftMargin = leftEdge;
					break;
				}
				publishProgress(leftMargin);
				sleep(20);
			}
			if(speed[0] > 0){
				isMenuVisible = true;
			}else {
				isMenuVisible = false;
			}
			
			return leftMargin;
		}
		
		private void sleep(int i) {
			try {
				Thread.sleep(i);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		@Override
		protected void onProgressUpdate(Integer... leftMargin) {
			menuParms.leftMargin = leftMargin[0];
			menu.setLayoutParams(menuParms);
		}
		
		@Override
		protected void onPostExecute(Integer leftMargin) {
			menuParms.leftMargin = leftMargin;
			menu.setLayoutParams(menuParms);
			
		}

	}
}
